﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Drawing;
using JcMBP_DES;

namespace PIM_ATE
{
    class JcPIMForCompat : JcPIMRunner
    {
        const string lf = "";
        //初始化状态
        bool m_isInited;
        //设备列表(NAME, IP)
        Dictionary<string, JcPIMInstrumentInfo> m_devices;
        //连接实例
        ClsJcPimCompat m_compatObj;
        //当前设置
        JcPIMDataSettings m_pim_settings;
        //结果列表
        List<JcPIMDataResults> m_pim_resultLists = new List<JcPIMDataResults>();
        //控制实例
        ImpCtrl m_ctrl;
        //异步句柄
        delegate bool DelStartTest();
       

        public JcPIMForCompat(Dictionary<string, JcPIMInstrumentInfo> devices)
        {
            m_devices = devices;
            m_compatObj = new ClsJcPimCompat(GDefine.IS_COMPAT_DEBUG_TEST);
            m_isInited = false;
            m_ctrl = new ImpCtrl();
        }

        public override void start_settings(JcPIMDataSettings settings)
        {
            m_pim_settings = settings;
            m_pim_resultLists.Clear();

            if (settings.isRandom || GDefine.IS_COMPAT_DEBUG_TEST)
            {
                m_compatObj.SetDebug(true);
                m_compatObj.SetDebugMaxMin(settings.RandomMax, settings.RandomMin);
            }
            else
            {
                m_compatObj.SetDebug(false);
            }
        }

        public override void start_test()
        {
            DelStartTest del_start_test = new DelStartTest(start_test_sync);
            del_start_test.BeginInvoke(evt_complete_test_async, del_start_test);
        }

        public override void stop_test()
        {
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = true;
            Monitor.Exit(m_ctrl);
        }

        bool start_test_sync()
        {
            bool complete = false;
            if (init(m_devices[m_pim_settings.Band_Name].instrAddress))
            {

                if (m_pim_settings.Mode == ImMode.Freq)
                    complete = freq_sweep();
                else
                    complete = time_sweep();
            }
            return complete;
        }

        void evt_show_msg(string msg, MSG_TYPE type)
        {
            //if (type != MSG_TYPE.LOG_NET)
            On_evt_show_log_handle(msg, null);

            if (type == MSG_TYPE.ERROR_NET || type == MSG_TYPE.ERROR_SET || type == MSG_TYPE.ERROR_TEST)
            {
                On_evt_show_error_handle(msg, null);
                //evt_complete_test(null, null);
            }
        }

        void evt_update_ui(object obj, EventArgs e)
        {//完成点事件
            On_evt_get_point_handle(obj, e);
        }

        void evt_complete_test_async(IAsyncResult result)
        {//完成测试事件(异步)
            bool complete = (result.AsyncState as DelStartTest).EndInvoke(result);

            if (m_isInited) m_compatObj.Close();
            m_isInited = false;
            evt_show_msg("connect: closen" + lf, MSG_TYPE.LOG_NET);

            if (complete)
                On_evt_complete_test_handle(m_pim_resultLists, null);
            else
                On_evt_complete_test_handle(null, null);
        }

        bool init(string address)
        {//初始化
            if (m_compatObj.Connect(address))
            {//连接
                evt_show_msg("connect: success" + lf, MSG_TYPE.LOG_NET);
                m_isInited = true;
            }
            else
            {
                m_isInited = false;
                evt_show_msg("connect-Error: " + m_compatObj.fnGetError()+ lf, MSG_TYPE.ERROR_NET);
            }

            return m_isInited;
        }

        bool freq_sweep()
        {//扫频
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);
           
            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;
            int sweeptype = 0;
           
   
            //ClsJcPimCompat.CHANNEL channel;
            //if (m_pim_settings.Channel == 0)
            //    channel = ClsJcPimCompat.CHANNEL.REV;
            //else
            //    channel = ClsJcPimCompat.CHANNEL.FWD;

            if (m_pim_settings.Channel == 0)
            {
                if (!m_compatObj.fnSetChannel(ClsJcPimCompat.CHANNEL.REV, 1))
                {//设置端口
                    evt_show_msg("exec-Error(fnSetChannel): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    return false;
                }
            }

            //if (!m_compatObj.fnSetTxOn(true))
            //{//开启功放
            //    evt_show_msg("exec-Error(fnSetTxOn): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
            //    return false;
            //}

            List<XPlot> lstPoint = new List<XPlot>();
            //扫频状态
            List<int> SweepType = new List<int>();
            List<int> IsUpSweep = new List<int>();
            List<int> IsDownSweep = new List<int>();
            double n1 = 0, n2 = 0, f = 0, g = 0;
            if (m_pim_settings.StepRx == 0)
            {//TX步进
                if (m_pim_settings.Step1 <= 0) m_pim_settings.Step1 = 1;
                n1 = Math.Ceiling((m_pim_settings.F1e - m_pim_settings.F1s) / m_pim_settings.Step1) + 1;
                if (m_pim_settings.Step2 <= 0) m_pim_settings.Step2 = 1;
                n2 = Math.Ceiling((m_pim_settings.F2e - m_pim_settings.F2s) / m_pim_settings.Step2) + 1;

                f = m_pim_settings.F1s;
                for (int i = 0; i < n1; ++i)
                {//上扫频
                    if (f > m_pim_settings.F1e) f = m_pim_settings.F1e;
                    double fpim = sumPIMFreq(f, m_pim_settings.F2e, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(f, m_pim_settings.F2e, fpim));
                    f += m_pim_settings.Step1;
                    if(IsUpSweep.Count == 0)
                    {
                        IsUpSweep.Add(0);
                    }
                    else
                    {
                        IsUpSweep.Add(1);
                    }

                }

                f = m_pim_settings.F2e;
                for (int i = 0; i < n2; ++i)
                {//下扫频
                    if (f < m_pim_settings.F2s) f = m_pim_settings.F2s;
                    double fpim = sumPIMFreq(m_pim_settings.F1s, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(m_pim_settings.F1s, f, fpim));
                    f -= m_pim_settings.Step2;
                    if (IsDownSweep.Count == 0)
                    {
                        IsDownSweep.Add(0);
                    }
                    else
                    {
                        IsDownSweep.Add(2);
                    }
                }
            }
            else
            {//rx步进
                double n = Math.Ceiling((m_pim_settings.RXe - m_pim_settings.RXs) / m_pim_settings.StepRx) + 1;
                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i, f += m_pim_settings.StepRx)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;

                    double f1 = sumF1FromPIMFreq(m_pim_settings.F2Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f1 >= m_pim_settings.F1Set && f1 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(f1, m_pim_settings.F2Set, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(f1, m_pim_settings.F2Set, g));
                        n1++;
                        if (IsUpSweep.Count == 0)
                        {
                            IsUpSweep.Add(0);
                        }
                        else
                        {
                            IsUpSweep.Add(1);
                        }
                    }

                    f1 = sumF2FromPIMFreq(m_pim_settings.F2Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f1 >= m_pim_settings.F1Set && f1 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(f1, m_pim_settings.F2Set, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(f1, m_pim_settings.F2Set, g));
                        n1++;
                        if (IsUpSweep.Count == 0)
                        {
                            IsUpSweep.Add(0);
                        }
                        else
                        {
                            IsUpSweep.Add(1);
                        }
                    }
                }

                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i, f += m_pim_settings.StepRx)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;
                    double f2 = sumF2FromPIMFreq(m_pim_settings.F1Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f2 >= m_pim_settings.F1Set && f2 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(m_pim_settings.F1Set, f2, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(m_pim_settings.F1Set, f2, g));
                        n2++;
                        if (IsDownSweep.Count ==0)
                        {
                            IsDownSweep.Add(0);
                        }
                        else
                        {
                            IsDownSweep.Add(2);
                        }
                    }

                    f2 = sumF1FromPIMFreq(m_pim_settings.F1Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f2 >= m_pim_settings.F1Set && f2 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(m_pim_settings.F1Set, f2, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(m_pim_settings.F1Set, f2, g));
                        n2++;
                        if (IsDownSweep.Count == 0)
                        {
                            IsDownSweep.Add(0);
                        }
                        else
                        {
                            IsDownSweep.Add(2);
                        }
                    }
                }
            }

            DateTime time = DateTime.Now;
            for(int j = 0; j < IsDownSweep.Count; j++)
            {
                IsUpSweep.Add(IsDownSweep[j]);
            }
            SweepType = IsUpSweep;
            int sweep = 0;
            #region 原循环测试
            for (int i = 0; i < lstPoint.Count; ++i)
            {//循环测试            
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {//手动结束
                    m_compatObj.fnSetTxOn(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }

                //freq_mhz = sumPIMFreq(lstPoint[i].X1, lstPoint[i].X2, (int)m_pim_settings.Order);
                freq_mhz = lstPoint[i].RX;

                evt_show_msg("exec: Set f1 = " + lstPoint[i].X1.ToString() + " ,f2 = " +
                                                 lstPoint[i].X2.ToString() + lf, MSG_TYPE.LOG_TEST);

                
                
                m_compatObj.fnSetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);
                m_compatObj.fnSetTxFreqs(lstPoint[i].X1, lstPoint[i].X2, "mhz");
                if (i == 0)
                {
                    if (!m_compatObj.fnSetFirstPoint())
                    {//设置第一个点的频率
                        System.Windows.Forms.MessageBox.Show("SetFirstPoint failed!");
                        return false;
                    }
                    m_compatObj.record_copy();
                    if (!m_compatObj.fnSetTxOn(true))
                    {//开启功放
                        evt_show_msg("exec-Error(fnSetTxOn): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                        return false;
                    }
                    
                }
                //if (freq_mhz < 698)
                //{
                //    //return false;
                //}
                if (!m_compatObj.fnGetImResult(freq_mhz, ref p1, ref p2, ref val, "mhz", SweepType[i]))
                { //读取PIM
                    m_compatObj.fnSetTxOn(false);
                    evt_show_msg("exec-Error(fnGetImResult): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    return false;
                }

                m_compatObj.record_copy();
                val += m_pim_settings.Offset_RX;

                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i + 1;
                entry.F1 = (float)lstPoint[i].X1;
                entry.F2 = (float)lstPoint[i].X2;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)Math.Round(p1, 1);
                entry.P2 = (float)Math.Round(p2, 1);
                entry.n1 = (int)n1;
                entry.n2 = (int)n2;
                if (m_pim_settings.isRandom)
                {
                    entry.Time_now = time;
                    time = time.AddSeconds(0.5);
                }
                else
                {
                    entry.Time_now = DateTime.Now;
                }

                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
            }
            #endregion
            if (!m_compatObj.fnResetPower())
            {//设置结束后的功率
                System.Windows.Forms.MessageBox.Show("ResetPower failed!");
                return false;
            }
            
            m_compatObj.record_copy();
            m_compatObj.fnSetTxOn(false);
            
            return true;
        }

        bool time_sweep()
        {//点频
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);

            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;
            int sweeptype = 0;
            


            //ClsJcPimCompat.CHANNEL channel;
            //if (m_pim_settings.Channel == 0)
            //    channel = ClsJcPimCompat.CHANNEL.REV;
            //else
            //    channel = ClsJcPimCompat.CHANNEL.FWD;

            if (m_pim_settings.Channel == 0)
            {
                if (!m_compatObj.fnSetChannel(ClsJcPimCompat.CHANNEL.REV, 1))
                {//设置端口
                    evt_show_msg("exec-Error(fnSetChannel): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    return false;
                }
            }

            //if(!m_compatObj.fnSetTxOn(true))
            //{//开启功放
            //    evt_show_msg("exec-Error(fnSetTxOn): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
            //    return false;
            //}

            //freq_mhz = sumPIMFreq(m_pim_settings.F1s, m_pim_settings.F2e, (int)m_pim_settings.Order);
            freq_mhz = m_pim_settings.RXs;
            evt_show_msg("exec: Set f1 = " + m_pim_settings.F1s.ToString() + " ,f2 = " +
                                             m_pim_settings.F2e.ToString() + lf, MSG_TYPE.LOG_TEST);

            m_compatObj.fnSetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);
            m_compatObj.fnSetTxFreqs(m_pim_settings.F1s, m_pim_settings.F2e, "mhz");

            if (!m_compatObj.fnSetFirstPoint())
            {//设置第一个点的频率
                System.Windows.Forms.MessageBox.Show("SetFirstPoint failed!");
                return false;
            }
            m_compatObj.record_copy();
            if (!m_compatObj.fnSetTxOn(true))
            {//开启功放
                evt_show_msg("exec-Error(fnSetTxOn): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            

            if (!m_compatObj.fnGetImResult(freq_mhz, ref p1, ref p2, ref val, "mhz", sweeptype))
            {//设置PIM第一点

                m_compatObj.fnSetTxOn(false);
                evt_show_msg("exec-Error(fnGetImResult): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            m_compatObj.record_copy();
            int i = 0;
            long time_start = DateTime.Now.Ticks;
            DateTime time = DateTime.Now;
            while (true)
            {
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {//手动结束测试
                    m_compatObj.fnSetTxOn(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }

                TimeSpan elapsedSpan = new TimeSpan(DateTime.Now.Ticks - time_start);
                if (elapsedSpan.TotalSeconds >= m_pim_settings.Time)
                {
                    break;
                }

                if (!m_compatObj.fnGetImResult(freq_mhz, ref val, "mhz"))
                {//读取PIM
                    m_compatObj.fnSetTxOn(false);
                    evt_show_msg("exec-Error(fnGetImResult): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    return false;
                }
                val += m_pim_settings.Offset_RX;

                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i;
                entry.F1 = (float)m_pim_settings.F1s;
                entry.F2 = (float)m_pim_settings.F2e;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)p1;
                entry.P2 = (float)p2;
                entry.n1 = 0;
                entry.n2 = 0;
                if (m_pim_settings.isRandom)
                {
                    entry.Time_now = time;
                    time = time.AddSeconds(0.5);
                }
                else
                {
                    entry.Time_now = DateTime.Now;
                }
                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
                i++;
            }
            if (!m_compatObj.fnResetPower())
            {//设置结束后的功率
                System.Windows.Forms.MessageBox.Show("ResetPower failed!");
                return false;
            }
            
            m_compatObj.record_copy();
            m_compatObj.fnSetTxOn(false);
            
            return true;
        }

    }
}
